﻿#ifndef JTHREAD_P_H
#define JTHREAD_P_H

#include "jthread.h"
#include <QThread>
#include "tools/jobjectobserver_p.h"

// - JThreadDelegate -

class JThreadDelegate : public QThread
{
    Q_OBJECT
    friend class JThread;
    friend class JThreadPrivate;
public:
    explicit JThreadDelegate(JThread *jthread, QObject *parent = 0)
        : QThread(parent)
        , jthread(jthread)
    {

    }

protected:
    virtual void run()
    {
        if (jthread) {
            jthread->run();
        }
    }

    int exec()
    {
        return QThread::exec();
    }

private:
    JThread *jthread;
};

// - class JThreadPrivate -

/**
 * @brief The JThreadPrivate class
 */
class JThreadPrivate : public QObject
{
    Q_OBJECT
    J_DECLARE_PUBLIC(JThread)
    J_DECLARE_OBSERVER_PRIVATE(JThread)
public:
    JThreadPrivate(JThread *jthread, QThread *other = 0, QObject *parent = 0)
        : q_ptr(jthread)
        , thread(other)
    {
        if (thread == 0) {
            thread = new JThreadDelegate(jthread, parent);
            connect(thread, SIGNAL(started()), this, SLOT(_emit_started()));
            connect(thread, SIGNAL(finished()), this, SLOT(_emit_finished()));
            connect(thread, SIGNAL(terminated()), this, SLOT(_emit_terminated()));
        }
    }

    ~JThreadPrivate()
    {
        if (thread && thread->parent() == 0) {
            thread->deleteLater();
        }
    }

    // extends
    void suspend()
    {
        suspendThread();
        J_EMIT_OBSERVER_PRIVATE(JThread, suspended());
    }

    void resume()
    {
        resumeThread();
        J_EMIT_OBSERVER_PRIVATE(JThread, resumed());
    }

protected:
    int exec()
    {
        if (thread->inherits("JThreadDelegate")) {
            return qobject_cast<JThreadDelegate *>(thread)->exec();
        } else {
            return -1;
        }
    }

private Q_SLOTS:
    void _emit_started()
    {
        J_EMIT_OBSERVER_PRIVATE(JThread, started());
    }

    void _emit_finished()
    {
        J_EMIT_OBSERVER_PRIVATE(JThread, finished());
    }

    void _emit_terminated()
    {
        J_EMIT_OBSERVER_PRIVATE(JThread, terminated());
    }

private:
    void init()
    {

    }

    static void suspendThread();
    static void resumeThread();

private:
    QThread *thread;
};

#endif // JTHREAD_P_H
